package com.gdhz.xiaohengqin.service;

import com.gdhz.xiaohengqin.model.entity.SysConfig;
import com.gdhz.xiaohengqin.repository.SysConfigRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;

/**
 * @author Swallows
 * @date 2025-06-09 15:19
 */
@Service
@RequiredArgsConstructor
public class SystemConfigService {

    private final SysConfigRepository configRepository;
    private final ReactiveRedisTemplate<String, String> redisTemplate;

    // Redis Key 前缀
    public static final String CACHE_PREFIX = "sys:config:";

    // 启动时加载所有配置到缓存
    @EventListener(ApplicationReadyEvent.class)
    public Mono<Void> loadAllConfigsOnStartup() {
        return configRepository.findAll()
                .flatMap(this::cacheConfig)
                .then();
    }

    // 获取配置（缓存优先）
    public Mono<String> getConfig(String paramKey) {
        String cacheKey = CACHE_PREFIX + paramKey;

        return redisTemplate.opsForValue().get(cacheKey)
                .switchIfEmpty(Mono.defer(()  ->
                        configRepository.findByParamKey(paramKey)
                                .flatMap(config ->
                                        cacheConfig(config).thenReturn(config.getParamValue())
                                )
                ));
    }

    // 更新配置（同时更新缓存和数据库）
    public Mono<SysConfig> updateConfig(String paramKey, String paramValue) {
        return configRepository.findByParamKey(paramKey)
                .flatMap(existing -> {
                    existing.setParamValue(paramValue);
                    existing.setUpdateTime(LocalDateTime.now());
                    return configRepository.save(existing);
                })
                .flatMap(this::cacheConfig);
    }

    // 缓存单个配置
    private Mono<SysConfig> cacheConfig(SysConfig config) {
        String cacheKey = CACHE_PREFIX + config.getParamKey();
        return redisTemplate.opsForValue()
                .set(cacheKey, config.getParamValue())
                .thenReturn(config);
    }

    // 定期刷新变更的配置
    @Scheduled(fixedRate = 300000) // 每5分钟刷新一次
    public Mono<Void> refreshModifiedConfigs() {
        return configRepository.findModifiedAfter(LocalDateTime.now().minusMinutes(5))
                .flatMap(this::cacheConfig)
                .then();
    }
}
